package com.xinyi.basic.base.dialog

import android.os.*
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import com.xinyi.basic.R
import com.xinyi.basic.thread.ThreadHandler

/**
 * @author 新一
 * @date 2023/10/19 13:54
 * @description Dialog弹窗碎片基类
 */
abstract class BaseDialogFragment : DialogFragment(), Handler.Callback {

    /**
     * 在工作线程上进行处理的Handler
     */
    private var mThreadHandler: ThreadHandler? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 设置弹窗样式
        setStyle(STYLE_NO_TITLE, setDialogStyleTheme())
        // 初始化Handler
        if (mThreadHandler == null) {
            mThreadHandler = ThreadHandler.createHandler(this)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            mThreadHandler?.quit()
            mThreadHandler = null
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(initLayoutId(), container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        dealIntent()
        initViews(view)
        initParams(savedInstanceState)
        initListeners()
    }

    /**
     * 初始化布局文件
     */
    abstract fun initLayoutId(): Int

    /**
     * 获取弹窗视图宽度
     */
    abstract fun getWindowWidth(): Int

    /**
     * 获取弹窗视图高度
     */
    abstract fun getWindowHeight(): Int

    /**
     * 设置弹窗样式
     */
    protected open fun setDialogStyleTheme(): Int = R.style.BaseDialogTheme

    /**
     * 设置弹窗在外部触摸时是否可以取消
     */
    protected open fun canceledOnTouchOutside(): Boolean = true

    /**
     * 设置弹窗是否可以通过物理返回键取消
     */
    protected open fun cancelable(): Boolean = true

    /**
     * 初始化视图
     */
    protected open fun initViews(view: View) {}

    /**
     * 初始化参数
     */
    protected open fun initParams(savedInstanceState: Bundle?) {
        dialog?.apply {
            // 设置弹窗在外部触摸时是否可以取消
            // 如果返回 true，用户点击弹窗外部时会关闭弹窗
            setCanceledOnTouchOutside(canceledOnTouchOutside())

            // 设置弹窗是否可以通过物理返回键取消
            // 如果返回 true，用户按下返回键时会关闭弹窗
            setCancelable(cancelable())

            //自定义弹窗视图宽高度
            window?.apply {
                setBackgroundDrawableResource(R.color.transparent)
                decorView.setPadding(0, 0, 0, 0)
                val wlp = attributes.apply {
                    gravity = Gravity.CENTER
                    width = getWindowWidth()
                    height = getWindowHeight()
                }
                attributes = wlp
            }
        }
    }

    /**
     * 处理Intent
     */
    protected open fun dealIntent() {}

    /**
     * 初始化监听器
     */
    protected open fun initListeners() {}

    /**
     * 处理消息
     */
    override fun handleMessage(msg: Message): Boolean {
        return false
    }

    /**
     * 在主线程上运行任务
     *
     * @param task 要执行的任务
     */
    @Synchronized
    fun runOnUiThread(task: Runnable?) {
        task ?: return
        mThreadHandler?.runOnUiThread(task)
    }

    /**
     * 在主线程上运行任务
     *
     * @param task 要执行的任务
     * @param duration 延迟执行的时间（毫秒）
     */
    @Synchronized
    fun runOnUiThread(task: Runnable?, duration: Long) {
        task ?: return
        mThreadHandler?.runOnUiThread(task, duration)
    }

    /**
     * 从主线程中移除指定的任务
     *
     * @param task 要移除的任务
     */
    @Synchronized
    fun removeFromUiThread(task: Runnable?) {
        task ?: return
        mThreadHandler?.removeFromUiThread(task)
    }

    /**
     * 将任务添加到队列中，在工作线程中执行
     *
     * @param task 要添加到队列中的任务
     */
    @Synchronized
    fun queueEvent(task: Runnable?) {
        task ?: return
        mThreadHandler?.queueEvent(task)
    }

    /**
     * 将任务添加到队列中，在工作线程中执行
     *
     * @param task 要添加到队列中的任务
     * @param delayMillis 延迟执行的时间（毫秒）
     */
    @Synchronized
    fun queueEvent(task: Runnable?, delayMillis: Long = 0) {
        task ?: return
        mThreadHandler?.queueEvent(task, delayMillis)
    }

    /**
     * 从队列中移除指定的任务
     *
     * @param task 要移除的任务
     */
    @Synchronized
    protected fun removeEvent(task: Runnable?) {
        task ?: return
        mThreadHandler?.removeEvent(task)
    }

    /**
     * 移除队列中的所有任务和消息
     */
    @Synchronized
    protected fun removeCallbacksAndMessages() {
        mThreadHandler?.removeCallbacksAndMessages()
    }

    /**
     * 发送消息到工作线程的消息队列中
     *
     * @param msg 要发送的消息对象
     */
    @Synchronized
    protected fun sendThreadMessageDelayed(msg: Message) {
        mThreadHandler?.sendThreadMessageDelayed(msg, 0)
    }

    /**
     * 发送线程消息/延迟
     *
     * @param msg 要发送的消息对象
     * @param delayMillis 延迟执行的时间（毫秒）
     */
    @Synchronized
    protected fun sendThreadMessageDelayed(msg: Message, delayMillis: Long = 0) {
        mThreadHandler?.sendThreadMessageDelayed(msg, delayMillis)
    }
}